//
#include <iostream>
#include "libzmq/zmq.h"
#include <string.h>
#include <stdio.h>
#include <thread>
#include "zguide/C/zhelpers.h"
#include "../protobuf/msg.pb.h"

// json
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

#define ZMQ_CLIENT_API
#define ZMQ_CONTEXT void *
#define ZMQ_SOCKET void *

ZMQ_CLIENT_API ZMQ_CONTEXT init_context()
{
	return zmq_ctx_new();
}

ZMQ_CLIENT_API ZMQ_SOCKET init_socket(ZMQ_CONTEXT context)
{
	return zmq_socket(context, ZMQ_REQ);
}

ZMQ_CLIENT_API int connect(ZMQ_SOCKET socket, std::string address)
{
	return zmq_connect(socket, address.c_str());
}

ZMQ_CLIENT_API int rpc(ZMQ_SOCKET socket, std::string func_id)
{
	rapidjson::Document d;
	d.SetObject();
	d.AddMember("id", "0311", d.GetAllocator());
	d.AddMember("name", "Jack", d.GetAllocator());
	d.AddMember("age", "20", d.GetAllocator());
	rapidjson::StringBuffer buffer;
	rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
	d.Accept(writer);

	msg m;
	m.set_funcid(func_id);
	m.set_data(buffer.GetString());
	std::string str_msg;
	m.SerializeToString(&str_msg);

	std::cout << "call:" << func_id.c_str() << std::endl;
	s_send(socket, const_cast<char *>(str_msg.c_str()));
	char *data = s_recv(socket);
	std::cout << "recv:" << data << std::endl;
	free(data);

	return 0;
}

ZMQ_CLIENT_API int close(ZMQ_SOCKET socket)
{
	return zmq_close(socket);
}

ZMQ_CLIENT_API int destroy(ZMQ_CONTEXT context)
{
	return zmq_ctx_destroy(context);
}

int main(void)
{
	ZMQ_CONTEXT context1 = init_context();
	ZMQ_SOCKET client1 = init_socket(context1);
	int res = connect(client1, "tcp://localhost:5559");

	while (1)
	{
		char text[128];
		std::cin >> text;
		rpc(client1, text);
	}

	close(client1);
	destroy(context1);

	return 0;
}
